<template>
  <div>
    <div v-if="mode === 'DESIGN'">
      <draggable class="l-drag-from" item-key="id" v-model="_columns" v-bind="dragProps"
        :component-data="{ tag: 'div', type: 'transition-group' }" @start="drag = true; selectFormItem = null"
        @end="drag = false">
        <template #item="{ element, index }">
          <div class="l-form-item" @click.stop="selectItem(element)" :style="getSelectedClass(element)">
            <div class="l-form-header">
              <p><span v-if="element.props.required">*</span>{{ $t(element.title) }}</p>
              <div class="l-option">
                <el-icon @click="delItem(index)">
                  <close />
                </el-icon>
              </div>
              <form-design-render :config="element" />
            </div>
          </div>
        </template>
      </draggable>
      <div style="color: #c0bebe; text-align: center; width: 90%; padding: 5px">
        ☝ {{ $t('module.controlsInside') }}
      </div>
    </div>
    <div v-else-if="mode === 'MOBILE'">
      <collapse v-model="actives">
        <div class="m-tb-empty" v-if="_value.length === 0">
          {{ $t('module.belowToAdd') }}
        </div>
        <collapse-item :lazy-render="false" style="background: #f7f8fa" :name="i" v-for="(row, i) in _value" :key="i">
          <template #title>
            <span>{{ $t('module.theFirst') }} {{ i + 1 }} {{ $t('module.item') }} </span>
            <span class="m-valid-error" v-if="isError(i)">
              <el-icon>
                <warning />
              </el-icon>
            </span>
            <span class="del-row" @click.stop="delRow(i, row)" v-if="!readonly">{{ $t('module.delete') }}</span>
          </template>
          <form-item :model="row" :rule="rules[column.id]" :ref="`${column.id}_${i}`" :prop="column.id"
            :label="$t(column.title)" v-for="(column, index) in _columns" :key="'column_' + index">
            <form-design-render :index="i + 1" :formData="formData" :readonly="isReadonly(column)"
              v-model="row[column.id]" :mode="mode" :config="column" />
          </form-item>
        </collapse-item>
      </collapse>
      <div class="m-add-row" @click="addRow" v-if="!readonly">
        <el-icon>
          <plus />
        </el-icon>
        <span> {{ $t(placeholder) }}</span>
      </div>
    </div>
    <template v-else>
      <template v-if="rowLayout == 1">
        <el-table :cell-style="cellStyle" :header-cell-style="tbCellStyle" :border="showBorder"
          :summary-method="getSummaries" :show-summary="showSummary" :data="_value" style="width: 100%">
          <el-table-column fixed type="index" :label="$t('module.serialNo')" width="55"></el-table-column>
          <template v-for="(column, index) in _columns">
            <el-table-column :min-width="getMinWidth(column)" :key="index" v-if="column.perm !== 'H'" :prop="column.id"
              :fixed="(index + 1) <= maxFixed" :label="$t(column.title)">
              <template #header>
                <span style="color: #da4b2b" v-show="column.props.required">*</span>
                {{ $t(column.title) }}
              </template>
              <template v-slot="scope">
                <form-design-render :index="scope.$index + 1" :formData="formData"
                  :class="{ 'valid-error': showError(column, _value[scope.$index][column.id]), 'readonly': readonly, }"
                  v-model="_value[scope.$index][column.id]" :readonly="isReadonly(column)" :mode="mode"
                  :config="column" />
              </template>
            </el-table-column>
          </template>
          <el-table-column fixed="right" :min-width="!readonly ? '160' : '70'" :label="$t('module.operation')">
            <template v-slot="scope">
              <el-button type="danger" size="small" style="width: auto;padding: 3px 5px !important;" v-if="!readonly"
                @click="delRow(scope.$index, scope.row)">{{ $t('module.delete') }}
              </el-button>
              <el-button type="primary" size="small" style="width: auto;padding: 3px 5px !important;" v-if="!readonly"
                @click="copyData(scope.$index, scope.row)">{{ $t('module.copys') }}
              </el-button>
              <el-button type="success" size="small" style="width: auto;padding: 3px 5px !important;"
                @click="look(scope.$index, scope.row)">{{ $t('webAuto.View') }}
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-button size="default" icon="plus" @click="addRow" v-if="!readonly">{{ $t(placeholder) }}</el-button>
      </template>
      <template v-else-if="rowLayout == 2">
        <el-form :rules="rules" :model="row" :ref="`table-form-${i}`" class="table-column" v-for="(row, i) in _value"
          :key="i">
          <div class="table-column-action">
            <span>{{ $t('module.theFirst') }} {{ i + 1 }} {{ $t('module.item') }}</span>
            <el-icon @click="delRow(i, row)" v-if="!readonly">
              <close />
            </el-icon>
          </div>
          <el-form-item v-for="(column, index) in _columns" :key="'column_' + index" :prop="column.id"
            :label="$t(column.title)">
            <form-design-render :index="i + 1" :formData="formData" :readonly="isReadonly(column)"
              v-model="row[column.id]" :mode="mode" :config="column" />
          </el-form-item>
        </el-form>
        <el-button size="small" icon="plus" @click="addRow" v-if="!readonly">{{ $t(placeholder) }}</el-button>
      </template>
      <template v-else>
        <el-table :cell-style="cellStyle" :header-cell-style="tbCellStyle" :border="showBorder"
          :summary-method="getSummaries" :show-summary="showSummary" :data="_value" style="width: 100%">
          <el-table-column fixed type="index" :label="$t('module.serialNo')" width="55"></el-table-column>
          <template v-for="(column, index) in _columns">
            <el-table-column :min-width="getMinWidth(column)" :key="index" v-if="column.perm !== 'H'" :prop="column.id"
              :fixed="(index + 1) <= maxFixed" :label="$t(column.title)">
              <template #header>
                <span style="color: #da4b2b" v-show="column.props.required">*</span>
                {{ $t(column.title) }}
              </template>
              <template v-slot="scope">
                <form-design-render :index="scope.$index + 1" :formData="formData"
                  :class="{ 'valid-error': showError(column, _value[scope.$index][column.id]), 'readonly': readonly, }"
                  v-model="_value[scope.$index][column.id]" :readonly="isReadonly(column)" :mode="mode"
                  :config="column" />
              </template>
            </el-table-column>
          </template>
          <el-table-column fixed="right" :min-width="!readonly ? '220' : '70'" :label="$t('module.operation')">
            <template v-slot="scope">
              <el-button type="danger" size="small" style="width: auto;padding: 3px 5px !important;" v-if="!readonly"
                @click="delRow(scope.$index, scope.row)">{{ $t('module.delete') }}
              </el-button>
              <el-button type="primary" size="small" style="width: auto;padding: 3px 5px !important;" v-if="!readonly"
                @click="copyData(scope.$index, scope.row)">{{ $t('module.copys') }}
              </el-button>
              <el-button type="warning" size="small" style="width: auto;padding: 3px 5px !important;" v-if="!readonly"
                @click="update(scope.$index, scope.row)">{{ $t('webAuto.edit') }}
              </el-button>
              <el-button type="success" size="small" style="width: auto;padding: 3px 5px !important;"
                @click="look(scope.$index, scope.row)">{{ $t('webAuto.View') }}
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-button size="default" icon="plus" @click="addRow2" v-if="!readonly">{{ $t(placeholder) }}</el-button>
      </template>
    </template>
    <!-- 弹框 -->
    <el-dialog v-model="tablePopup" :title="popupTitle" :top="lookButton ? '' : '1vh'" width="70%"
      :before-close="handleClose" :close-on-click-modal="false" :max-height="dialogMaxHeight" class="custom-dialog">
      <el-form :rules="rules" :model="row" :ref="`table-form-${i}`" v-for="(row, i) in [rowLi]" :key="i">
        <el-row :gutter="20">
          <template v-for="(column, index) in _columns">
            <el-col :span="6" style="margin-bottom: 13px;" v-if="column?.perm !== 'H'" :key="'column_' + index">
              <el-form-item :prop="column.id" :label="$t(column.title)" :required=column.props.required >
                <form-design-render @data-selected="handleDataSelected" :index="i + 1" :formData="formData"  :rowLayout="rowLayout"
                  :readonly="isReadonly(column)" v-model="row[column.id]" :mode="mode" :config="column" />
              </el-form-item>
            </el-col>
          </template>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <!--取消 追加 新增 -->
          <el-button @click="tablePopup = false">{{ $t('calendar.cancel') }}</el-button>
          <el-button type="warning" @click="confirmClick2(_columns)" v-if="!showButton && !lookButton">
            {{ $t('calendar.readdition') }}
          </el-button>
          <el-button type="primary" @click="confirmClick(_columns)" v-if="!showButton && !lookButton">
            {{ $t('calendar.confirm') }}
          </el-button>
          <!-- 更新 -->
          <el-button type="primary" @click="updateClick" v-if="showButton && !lookButton">{{
            $t('calendar.confirm')
          }}
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
import { ValueType } from '../ComponentsConfigExport'
import { Collapse, CollapseItem, showConfirmDialog, showFailToast } from 'vant'
import FormItem from '@/components/common/FormItem.vue'
import FormDesignRender from '@/views/admin/layout/form/FormDesignRender.vue'
import componentMinxins from '../ComponentMinxins'

export default {
  mixins: [componentMinxins],
  name: 'TableList',
  components: { draggable, FormItem, Collapse, CollapseItem, FormDesignRender },
  props: {
    modelValue: {
      type: Array,
      default: () => {
        return []
      },
    },
    placeholder: {
      type: String,
      default: '添加数据',
    },
    columns: {
      type: Array,
      default: () => {
        return []
      },
    },
    showBorder: {
      type: Boolean,
      default: true,
    },
    showSummary: {
      type: Boolean,
      default: false,
    },
    maxSize: {
      type: Number,
      default: 0,
    },
    maxFixed: {
      type: Number,
      default: 0,
    },
    precision: {
      type: Number,
      default: 2,
    },
    rowLayout: {
      type: Number,
      default: 1,
    },
    logic: {
      type: String,
      default: 'function doTableChange(formData2,formData, formMap) {}',
    },
    formData: {
      type: Object,
      default: () => {
        return {}
      },
    },
  },
  created() {
    console.log('TextSelector',this.rowLayout)
    if (!Array.isArray(this.modelValue)) {
      this._value = []
    }
  },
  computed: {
    rules() {
      const rules = {}
      this.columns.forEach((col) => {
        if (col.props.required && col.perm === 'E') {
          rules[col.id] = [
            {
              type: ValueType.getValidType(col.valueType),
              required: true,
              message: `${this.$t('title.pleaseComplete')}${this.$t(col.title)}`,
              trigger: 'blur',
            },
          ]
        }
      })
      return rules
    },
    _columns: {
      get() {
        return this.columns
      },
      set(val) {
        this.$emit('update:columns', val)
      },
    },
    selectFormItem: {
      get() {
        return this.$store.state.selectFormItem
      },
      set(val) {
        this.$store.state.selectFormItem = val
      },
    },
  },
  data() {
    return {
      select: null,
      drag: false,
      ValueType,
      actives: [],
      reload: 0,
      tbCellStyle: {
        background: '#e8e8e8',
        padding: '10px 0',
      },
      cellStyle: {
        padding: '0',
      },
      dragProps: {
        animation: 300,
        group: "form",
        disabled: false,
        sort: true,
        ghostClass: "choose",
      },
      tablePopup: false,
      rowLi: {},
      showButton: false,
      dialogMaxHeight: this.calculateDialogMaxHeight(),
      popupTitle: '弹框明细',
      lookButton: false,
    }
  },
  methods: {
    handleDataSelected(data) {
      this.mergeExceptKey(data, this.rowLi, 'tableId')
    },
    mergeExceptKey(source, target, excludeKey) {
      for (const key in source) {
        if (key !== excludeKey) {
          target[key] = source[key];
        }
      }
    },
    isReadonly(item) {
      return item.perm === 'R'
    },
    calculateDialogMaxHeight() {
      // 计算对话框的最大高度，例如占屏幕高度的 80%
      const screenHeight = window.innerHeight;
      return `${screenHeight * 0.8}px`;
    },
    getMinWidth(col) {
      switch (col.name) {
        case 'DateTime':
          return '150px'
        case 'TimeRangePicker':
          return '220px'
        case 'DateTimeRange':
          return '240px'
        case 'MultipleSelect':
          return '220px'
        default:
          return '200px'
      }
    },
    showError(col, val) {
      if (col.props.required) {
        switch (col.valueType) {
          case ValueType.dept:
          case ValueType.user:
          case ValueType.dateRange:
          case ValueType.array:
            return !(Array.isArray(val) && val.length > 0)
          default:
            return !this.$isNotEmpty(val)
        }
      }
      return false
    },
    isError(i) {
      for (let j = 0; j < this._columns.length; j++) {
        let ref = this.$refs[`${this._columns[j].id}_${i}`]
        if (ref && Array.isArray(ref) && ref.length > 0 && ref[0].isError) {
          if (ref[0].isError()) {
            return true
          }
        }
      }
      return false
    },
    // 复制 表格行
    copyData(i, row) {
      let copeLi={}
      this.mergeExceptKey(row, copeLi, 'tableId')
      // 处理表格行id重复的问题
      copeLi.tableId=this.getMaxTableId()
      this._value.push(this.$deepCopy(copeLi))
    },
    delRow(i, row) {
      if (this.mode === 'PC') {
        this.$confirm(this.$t('webAuto.AreYouSuer'), this.$t('webAuto.prompt'), {
          confirmButtonText: this.$t('webAuto.sure'),
          cancelButtonText: this.$t('webAuto.cancel'),
          type: 'warning',
        }).then(() => {
          this._value.splice(i, 1)
        })
      } else {
        showConfirmDialog({
          title: this.$t('webAuto.prompt'),
          message: this.$t('webAuto.AreYouSuer'),
        }).then(() => {
          this._value.splice(i, 1)
        })
      }
    },
    // 表格添加的时候出发 不是弹框模式的情况下使用
    addRow() {
      if (this.maxSize > 0 && this._value.length >= this.maxSize) {
        if (this.mode === 'PC') {
          this.$message.warning(this.$t('webAuto.moreAdd') + this.maxSize + this.$t('webAuto.hang'))
        } else {
          showFailToast(this.$t('webAuto.moreAdd') + this.maxSize + this.$t('webAuto.hang'))
        }
      } else {
        let row = {}
        this.columns.forEach((col) => (row[col.id] = undefined))
        const v = Object.assign([], this._value)
        // 表格添加行时，设置表格行号id
        row.tableId = this.getMaxTableId()
        v.push(row)
        this._value = v
      }
    },
    // 表格添加的时候出发 弹框模式的情况下使用
    addRow2() {
      this.showButton = false
      if (this.maxSize > 0 && this._value.length >= this.maxSize) {
        if (this.mode === 'PC') {
          this.$message.warning(this.$t('webAuto.moreAdd') + this.maxSize + this.$t('webAuto.hang'))
        } else {
          showFailToast(this.$t('webAuto.moreAdd') + this.maxSize + this.$t('webAuto.hang'))
        }
      } else {
        let row = {}
        this.columns.forEach((col) => (row[col.id] = undefined))
        const v = Object.assign([], this._value)
        // 表格添加行时，设置表格行号id
        row.tableId = this.getMaxTableId()
        // this.rowLi = row
        this.mergeExceptKey(row, this.rowLi, '')
      }
      this.tablePopup = true
      this.lookButton = false
      this.popupTitle = '添加表格明细行'
    },
    // 添加 的确定
    confirmClick(column) {
      // CalcFormula 排查计算公式组件
      let rowRequired = column.filter(x => (!this.rowLi[x.id]) && x.props.required &&x.perm!='H'&& x.name!="CalcFormula")
      if (rowRequired.length) {
        let title
        rowRequired.forEach(x=>{
          title=x.title+','+title
        })
        this.$message.warning(this.$t('请正确填写明细表的必填项（* 表示必填）。具体没有填写字段为'+title.split(',undefined')[0]));
      } else {
        const v = Object.assign([], this._value)
        // v.push(this.rowLi)
        v.push(JSON.parse(JSON.stringify(this.rowLi)))
        this._value = v
        this.tablePopup = false
      }
    },
    // 追加
    confirmClick2(column) {
      let rowRequired = column.filter(x => (!this.rowLi[x.id]) && x.props.required && x.name!="CalcFormula")
      if (rowRequired.length) {
        let title
        rowRequired.forEach(x=>{
          console.log('x.title', x)
          title=x.title+','+title
        })
        this.$message.warning(this.$t('请正确填写明细表的必填项（* 表示必填）。具体没有填写字段为'+title.split(',undefined')[0]));
      } else {
        const v = Object.assign([], this._value)
        v.push(JSON.parse(JSON.stringify(this.rowLi)))
        this._value = v
        // 追加完成清空
        let row = {}
        this.columns.forEach((col) => (row[col.id] = undefined))
        // 表格添加行时，设置表格行号id
        row.tableId = this.getMaxTableId()
        // console.log(' row.tableId', row.tableId)
        // this.rowLi = row
        this.mergeExceptKey(row, this.rowLi, '')
      }
    },
    // 查找存在的tableId 最大值 使用的时候永远最大值加1
    getMaxTableId() {
      const ids = this._value
        .filter(x => x?.tableId !== undefined)
        .map(x => x?.tableId);
      return ids.length ? Math.max(...ids)+1 : (this._value.length + 1);
    },
    // 更新
    update(i, row) {
      this.popupTitle = '编辑表格明细行'
      this.showButton = true
      this.tablePopup = true
      // 打开编辑先重置rowLi,然后再进行赋值
      this.rowLi = {}
      this.mergeExceptKey(row, this.rowLi, '')
      this.lookButton = false
    },
    updateClick() {
      this._value.forEach(item => {
        if (item.tableId == this.rowLi.tableId) {
          this.mergeExceptKey(this.rowLi, item, 'tableId')
        }
      })
      this.tablePopup = false
    },
    // 查看
    look(i, row) {
      this.lookButton = true
      this.tablePopup = true
      this.popupTitle = '查看表格明细行'
      this.mergeExceptKey(row, this.rowLi, '')
    },
    handleClose() {
      this.tablePopup = false
      this.rowLi = {}
      this.showButton = false
    },
    delItem(id) {
      this._columns.splice(id, 1)
    },
    selectItem(cp) {
      this.selectFormItem = cp
    },
    getSelectedClass(cp) {
      return this.selectFormItem && this.selectFormItem.id === cp.id
        ? 'border-left: 4px solid #f56c6c'
        : ''
    },
    getSummaries(param) {
      const { columns, data } = param
      const sums = []
      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = '合计'
          return
        }
        const foundColumn = column.property !== undefined && this.columns.find(x => x.id === column.property);
        if (column.label.indexOf("*") != -1 || foundColumn.name === "NumberInput" || foundColumn.name === "AmountInput") {
          const values = data.map((item) => Number(item[column.property]))
          if (!values.every((value) => isNaN(value))) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr)
              if (!isNaN(value)) {
                return prev + curr
              } else {
                return prev
              }
            }, 0).toFixed(this.precision || 2)
          } else {
            sums[index] = '...'
          }
        }
      })

      return sums
    },
    validate(call) {
      if (this.mode === 'PC') {
        if (this.rowLayout == 1 || this.rowLayout == 3) {
          let result = true
          for (let i = 0; i < this.columns.length; i++) {
            if (this.columns[i].props.required && this.columns[i].perm === 'E') {
              for (let j = 0; j < this._value.length; j++) {
                result = !this.showError(
                  this.columns[i],
                  this._value[j][this.columns[i].id]
                )
                if (!result) {
                  call(false)
                  return
                }
              }
            }
          }
          call(result)
        } else if (this.rowLayout == 2) {
          let success = 0
          this._value.forEach((v, i) => {
            let formRef = this.$refs[`table-form-${i}`]
            if (formRef && Array.isArray(formRef) && formRef.length > 0) {
              formRef[0].validate((valid) => {
                if (valid) {
                  success++
                }
              })
            }
          })
          setTimeout(() => call(success === this._value.length), 500)
        }
      } else {
        let success = true
        if (Array.isArray(this._value) && this._value.length > 0) {
          this._value.forEach((row, i) => {
            this._columns.forEach((col) => {
              let tbColRef = this.$refs[`${col.id}_${i}`]
              if (tbColRef && Array.isArray(tbColRef) && tbColRef.length > 0) {
                tbColRef[0].validate((valid) => {
                  if (!valid) {
                    success = false
                  }
                })
              }
            })
          })
        } else {
          success = false
        }
        call(success)
      }
    },
  },
  emits: ['update:modelValue'],
  watch: {
    rowLi: {
      handler(newVal, oldVal) {
         // console.log('rowLi 发生变化:', oldVal);
         let a=new Function(`${this.logic||'function doTableChange(formData2,formData,oldVal, formMap) {}'}\r\n return doTableChange`)
         // 调用自定义函数
         a(newVal)(newVal,this.formData,oldVal)
      },
      deep: true
    },
    _value: {
      handler(newVal, oldVal) {
        // 将newval克隆给 this.rowLi
        // console.log('_value 发生变化:', newVal);
      },
      deep: true
    }
  }
}
</script>

<style lang="less" scoped>
.custom-dialog {
  .el-dialog__body {
    max-height: calc(80vh - 200px); // 根据需要调整
    overflow-y: auto;
  }
}

.m-valid-error {
  margin-left: 10px;
  font-size: 1rem;
  color: @theme-danger;
}

.readonly {
  padding: 5px 0;
}

:deep(.m-form-item .valid-error) {
  border-bottom: none;
}

.del-row {
  float: right;
  margin-right: 10px;
  font-size: 1rem;
  color: #8c8c8c;
}

:deep(.valid-error) {
  border-bottom: 4px dashed @theme-danger;
  margin:5px 0 7px 0;
}

.choose {
  border: 1px dashed @theme-primary !important;
}

:deep(.el-table__row) {
  .el-input.is-focus .el-input__wrapper {
    box-shadow: none;
  }

  .cell {

    .el-input__wrapper,
    .el-input__inner,
    .el-textarea__inner {
      border-radius: 0;
      border: none;
      padding-left: 0;
      box-shadow: none;
    }

    .el-input__prefix {
      display: none;
    }
  }
}


.table-column {
  padding: 5px;
  margin-bottom: 10px;
  border-left: 3px solid @theme-primary;
  border-radius: 5px;
  background: #fafafa;

  :deep(.el-form-item) {
    margin-bottom: 20px;

    .el-form-item__label {
      height: 25px;
    }
  }

  .table-column-action {
    float: right;

    span {
      color: #afafaf;
      margin-right: 10px;
      font-size: 13px;
    }

    .icon {
      color: #afafaf;
      padding: 5px;
      font-size: large;
      cursor: pointer;

      &:hover {
        color: #666666;
      }
    }
  }
}

.l-drag-from {
  min-height: 50px;
  background-color: rgb(245, 246, 246);

  .l-form-item,
  li {
    cursor: grab;
    background: #ffffff;
    padding: 10px;
    border: 1px solid #ebecee;
    margin: 5px 0;
  }
}

.m-add-row {
  color: @theme-primary;
  padding-top: 10px;
  text-align: center;
  cursor: pointer;
}

:deep(.van-collapse-item__content) {
  padding: 0;
  background: #f7f8fa;
}


.m-tb-empty {
  padding: 20px;
  background: #f7f8fa;
  color: #bdb7b7;
  text-align: center;
}

.l-form-header {
  font-size: small;
  color: #818181;
  text-align: left;
  position: relative;
  background-color: #fff;

  p {
    position: relative;
    margin: 0 0 10px 0;

    span {
      position: absolute;
      left: -8px;
      top: 3px;
      color: rgb(217, 0, 19);
    }
  }

  .l-option {
    position: absolute;
    top: -10px;
    right: -10px;

    .icon {
      font-size: large;
      cursor: pointer;
      color: #8c8c8c;
      padding: 5px;

      &:hover {
        color: @theme-primary;
      }
    }
  }
}
</style>
